home *** CD-ROM | disk | FTP | other *** search
- /* Listing 5 TOPDOWN2.C -- Cleaned-up Parser */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include "lex.h"
-
- void statement ( void );
- void expression_and_predicate ( void );
- void mult_expr_and_predicate ( void );
- void factor ( void );
- void error (char *fmt,...);
-
- #ifdef PTRACE
- static int Rdepth = 0;
- int rdepth(void) {return( Rdepth * 8 );}
- # define trace(name) printf("%*s%s\n", Rdepth++ * 8, "", name)
- # define untrace(name) (--Rdepth)
- #else
- # define trace(name) /* empty */
- # define untrace(name) /* empty */
- #endif
- /*----------------------------------------------------------------------*/
- void statement( void )
- {
- /* statement->WHILE LP expression RP statement WHILE
- * statement->expression SEMI LP SEMI ID NUMBER
- *
- * Modified to eliminate tail recursion.
- */
-
- trace("statement");
- if( match(LP) || match(SEMI) || match(ID) || match(NUMBER) )
- {
- expression_and_predicate();
-
- if( match(SEMI) ) advance();
- else error("Inserting missing semicolon.");
- }
- else if( !match(WHILE) )
- error( "while loop or expression expected\n" );
-
- else while( match(WHILE) )
- {
- advance();
-
- if( match(LP) ) advance();
- else error("Inserting missing left parenthesis.");
-
- expression_and_predicate();
-
- if( match(RP) ) advance();
- else error("Inserting missing right parenthesis.");
- }
-
- untrace("statement");
- }
- /*----------------------------------------------------------------------*/
- void expression_and_predicate( void )
- {
- /* expression->mult_expr predicate LP ID NUMBER
- * expression->(epsilon) RP SEMI
- *
- * Modified to incorporate the predicate productions and also
- * to eliminate the tail recursion in the original predicate();
- */
-
- trace("expression_and_predicate");
-
- if( match(RP) || match(SEMI) )
- ; /* epsilon */
-
- else if( !(match(LP) || match(ID) || match(NUMBER)) )
- error( "expression expected\n" );
- else
- {
- mult_expr_and_predicate();
-
- /* predicate->PLUS mult_expr predicate PLUS
- * predicate->MINUS mult_expr predicate MINUS
- * predicate->(epsilon) RP SEMI
- */
-
- if( match(RP) || match(SEMI) )
- ; /* epsilon */
-
- else if( !(match(PLUS) || match(MINUS)) )
- error("operator or statement-terminator expected\n");
-
- else while( match(PLUS) || match(MINUS) )
- {
- advance();
- mult_expr_and_predicate();
- }
- }
- untrace("expression_and_predicate");
- }
- /*----------------------------------------------------------------------*/
- void mult_expr_and_predicate( void )
- {
- /* mult_expr->factor mult_predicate LP ID NUMBER
- *
- * Modified to eliminate chain to mult_predicate() and also
- * eliminate tail recursion in mult_predicate();
- */
-
- trace("mult_expr_and_predicate");
-
- if( !(match(LP) || match(ID) || match(NUMBER)) )
- error( "expected number identifier or open parenthesis\n" );
- else
- {
- factor();
-
- /* mult_predicate->STAR factor mult_predicate STAR
- * mult_predicate->SLASH factor mult_predicate SLASH
- * mult_predicate->(epsilon) RP PLUS MINUS SEMI
- */
-
- if( match(RP) || match(PLUS) || match(MINUS) || match(SEMI) )
- ; /* epsilon */
- else if( !(match(STAR) || match(SLASH)) )
- error("operator expected\n");
-
- else while( match(STAR) || match(SLASH) )
- {
- advance();
- factor();
- }
- }
-
- untrace("mult_expr_and_predicate");
- }
- /*----------------------------------------------------------------------*/
- void factor( void )
- {
- /* factor->NUMBER NUMBER
- * factor->ID ID
- * factor->LP expression RP LP
- */
-
- trace( "factor" );
-
- if( match(NUMBER) || match(ID) )
- advance();
- else if( match(LP) )
- {
- advance();
- expression_and_predicate();
-
- if( match(RP) ) advance();
- else error("Inserting missing right parenthesis.");
- }
-
- untrace( "factor" );
- }
- /*----------------------------------------------------------------------*/
- void error( char *fmt, ... )
- {
- va_list args;
- va_start( args, fmt );
- vfprintf( stderr, fmt, args );
- va_end( args );
- }
- /*----------------------------------------------------------------------*/
- int main()
- {
- statement();
- return 0;
- }